package br.com.ordersys.web.client.modules.login;

import br.com.ordersys.web.client.modules.broker.CallBack;
import br.com.ordersys.web.client.modules.broker.ServiceBroker;
import br.com.ordersys.web.client.modules.broker.ServiceCall;
import br.com.ordersys.web.client.modules.broker.ServiceResponse;
import br.com.ordersys.web.client.modules.uicomp.BasicResources;
import br.com.ordersys.web.client.modules.uicomp.ErrorBox;
import br.com.ordersys.web.client.modules.utils.CryptUtils;
import br.com.ordersys.web.client.modules.utils.I18nBundle;
import br.com.ordersys.web.client.modules.utils.StringUtils;
import br.com.ordersys.web.client.modules.utils.UIUtils;
import br.com.ordersys.web.client.modules.utils.XMLUtils;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.xml.client.Document;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.XMLParser;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class LoginUI implements EntryPoint {
	private ErrorBox lblError;
	private FormPanel form;
	private I18nBundle i18n = new I18nBundle("login");

	static{
		BasicResources.INSTANCE.basicStyle().ensureInjected();
	}
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		RootPanel mainPnl = RootPanel.get("_main");
		form = new FormPanel();
		form.setAction(UIUtils.buildAppBaseURI("afterlogin"));
	    form.setMethod(FormPanel.METHOD_POST);

		final TextBox txtUserName = new TextBox();
		txtUserName.setName("userName");
		
		txtUserName.setStyleName(BasicResources.INSTANCE.basicStyle().loginTextField());
		txtUserName.getElement().setAttribute("autocomplete", "true");	
		txtUserName.getElement().setAttribute("type", "email");	

		final PasswordTextBox txtPassword = new PasswordTextBox();
		txtPassword.addKeyPressHandler(new KeyPressHandler() {
			
			@Override
			public void onKeyPress(KeyPressEvent e) {
				if(e.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER){
					doLogin(txtUserName.getText(), txtPassword.getText());
				}
			}
		});
		
		txtPassword.setStyleName(BasicResources.INSTANCE.basicStyle().loginTextField());

		lblError = new ErrorBox();
		lblError.setStyleName(BasicResources.INSTANCE.basicStyle().error());
		UIUtils.setWidgetStyle(lblError,"maxWidth: 256px");

		VerticalPanel pnlVertical = new VerticalPanel();
		pnlVertical.setSpacing(5);

		Label lblNomeUsuario = new Label(i18n.get("lbl_user_name"));
		lblNomeUsuario.setStyleName(BasicResources.INSTANCE.basicStyle().loginLabel());

		Label lblPass = new Label(i18n.get("lbl_user_password"));
		lblPass.setStyleName(BasicResources.INSTANCE.basicStyle().loginLabel());

		pnlVertical.add(lblNomeUsuario);
		pnlVertical.add(txtUserName);
		pnlVertical.add(buildEmptySpace("1px", "20px"));
		pnlVertical.add(lblPass);
		pnlVertical.add(txtPassword);
		pnlVertical.add(lblError);

		pnlVertical.add(buildBottomPanel(txtUserName, txtPassword));

		pnlVertical.setVerticalAlignment(pnlVertical.ALIGN_MIDDLE);

		form.add(pnlVertical);
		
		mainPnl.add(form);
	}
	
	private Panel buildEmptySpace(String width, String height){
		Panel p = new SimplePanel();
		p.setWidth(width);
		p.setHeight(height);
		return p;
	}

	private Panel buildBottomPanel(final TextBox userName, final TextBox passw) {
		Button btnLogin = new Button(i18n.get("btn_entry"));
		btnLogin.setStyleName(BasicResources.INSTANCE.basicStyle().defaultButton());

		Hyperlink hpl = new Hyperlink();
		hpl.setText(i18n.get("lnk_password_recovery"));
		hpl.addHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent e) {
				passwordRecovery(userName.getText());
			}
		}, ClickEvent.getType());
		
		HorizontalPanel pnlHoriz = new HorizontalPanel();
		pnlHoriz.setWidth("100%");

		pnlHoriz.add(btnLogin);
		pnlHoriz.add(hpl);

		pnlHoriz.setCellHorizontalAlignment(btnLogin, HorizontalPanel.ALIGN_LEFT);
		pnlHoriz.setCellVerticalAlignment(btnLogin, HorizontalPanel.ALIGN_MIDDLE);
		pnlHoriz.setCellHorizontalAlignment(hpl, HorizontalPanel.ALIGN_RIGHT);
		pnlHoriz.setCellVerticalAlignment(hpl, HorizontalPanel.ALIGN_MIDDLE);

		btnLogin.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent e) {
				doLogin(userName.getText(), passw.getText());
			}
		});

		return pnlHoriz;
	}
	
	protected void passwordRecovery(final String user) {
		if(user == null || user.trim().length() == 0){
			lblError.setMessage(i18n.get("msg_entry_user_name"));
			return;
		}
		
		ServiceCall sc = new ServiceCall("user", "sendPasswordRecoveryMessage");

		Document xml = XMLParser.createDocument();

		Element reqBody = xml.createElement("obj");
		
		reqBody.appendChild(XMLUtils.createElement(xml, "email", user));

		sc.setServiceBody(reqBody);
		sc.setHandleErrors(true);

		sc.setResponseCallBack(new CallBack() {
			@Override
			public void onResponse(ServiceResponse response) {
				if(response.getStatus() == 0){
					Window.alert(StringUtils.format(i18n.get("msg_password_recovery_note"),user));
				}else{
					lblError.setMessage(response.getMessage());
				}
			}
		});

		ServiceBroker sb = new ServiceBroker();

		sb.call(sc);
	}

	private void doLogin(String user, String passw) {
		if(user == null || user.trim().length() == 0){
			lblError.setMessage(i18n.get("msg_entry_user_name"));
			return;
		}
		
		lblError.clear();
		
		user = user.trim();
		
		ServiceCall sc = new ServiceCall("user", "login");

		Document xml = XMLParser.createDocument();

		passw = passw == null || passw.trim().length() == 0 ? "" : passw.trim();
		Element reqBody = xml.createElement("obj");
		
		reqBody.appendChild(XMLUtils.createElement(xml, "email", user));
		reqBody.appendChild(XMLUtils.createElement(xml, "password", CryptUtils.getMD5for(passw)));

		sc.setServiceBody(reqBody);
		sc.setHandleErrors(true);

		sc.setResponseCallBack(new CallBack() {
			@Override
			public void onResponse(ServiceResponse response) {
				if(response.getStatus() == 0){
					form.submit(); //submetemos o formulário apenas para salvar o nome de usuário no histórico de campos do navegador
					UIUtils.callLater(new Runnable() {
						@Override
						public void run() {
							Window.Location.assign(UIUtils.buildAppBaseURI("MainWindow.page"));
						}
					});
				}else{
					lblError.setMessage(response.getMessage());
				}
			}
		});

		ServiceBroker sb = new ServiceBroker();

		sb.call(sc);
	}
}
